package com.midea.freecolder;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description：
 * 1、synchronized和Lock差异：
 *      Condition可以定义多个，而synchronized的锁对象只能是一个
 * 2、可重入锁：统一线程对某一锁多次加锁，不会产生死锁例如：
 *      lock.lock();
 *      lock.lock();
 *      System.out.println(1);
 *      lock.unlock();
 *      lock.unlock();
 *      如果不可重入，这段代码就是自己和自己死锁了
 * 3、线程进入block状态的三种方法
 *      wait
 *      sleep
 *      join
 * @author: wangwl23
 * @create: 2021-07-23 14:03
 */
public class Concurrent3 {
    static Object obj = new Object();
    static Lock lock = new ReentrantLock();
    static Condition c1 = lock.newCondition();

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            test1();
            //test2();
            //test3();
        }
        Thread.sleep(2000);
        /*synchronized (obj) {
            obj.notifyAll();
        }*/
        //主线程唤醒其他线程的时候也要先获得锁对象
       /* lock.lock();
        c1.signalAll();
        lock.unlock();*/
    }

    private static void test1() {
        Thread t = new Thread(() -> {
            synchronized (obj) {
                try {
                    obj.wait();
                    System.out.println("hello");
                    //Thread.sleep(1000);
                    while(true){

                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        //中断线程
        t.interrupt();
    }

    private static void test2() {
        Thread t = new Thread(() -> {
            boolean b = false;
            try {
                b = lock.tryLock(1500L, TimeUnit.MILLISECONDS);
                if(b){
                    System.out.println("hello2");
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (b) {
                    lock.unlock();
                }
            }
        });
        t.start();
    }


    private static void test3() {
        Thread t = new Thread(() -> {
            try {
                lock.lock();
                c1.await();
                System.out.println("hello2");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });
        t.start();
    }

}
